From b1cf3deb811b8d4cb9c36146f0f5ea046d8f4062 Mon Sep 17 00:00:00 2001 From: Emmanuel Ackaouy Date: Fri, 5 Jan 2007 17:34:43 +0000 Subject: [PATCH] Support for save and restore of compatibility guests Signed-off-by: Emmanuel Ackaouy --- tools/libxc/xc_linux_save.c | 27 ++++++++++++++++++++------- tools/libxc/xg_save_restore.h | 9 +++++++++ xen/arch/x86/domctl.c | 5 ++++- xen/include/asm-x86/x86_64/page.h | 2 +- 4 files changed, 34 insertions(+), 9 deletions(-) diff --git a/tools/libxc/xc_linux_save.c b/tools/libxc/xc_linux_save.c index 44dba99cd5..7ca8453848 100644 --- a/tools/libxc/xc_linux_save.c +++ b/tools/libxc/xc_linux_save.c @@ -44,6 +44,7 @@ static xen_pfn_t *live_p2m = NULL; /* Live mapping of system MFN to PFN table. */ static xen_pfn_t *live_m2p = NULL; +static unsigned long m2p_mfn0; /* grep fodder: machine_to_phys */ @@ -440,13 +441,23 @@ static int canonicalize_pagetable(unsigned long type, unsigned long pfn, ** that this check will fail for other L2s. */ if (pt_levels == 3 && type == XEN_DOMCTL_PFINFO_L2TAB) { - -/* XXX index of the L2 entry in PAE mode which holds the guest LPT */ -#define PAE_GLPT_L2ENTRY (495) - pte = ((const uint64_t*)spage)[PAE_GLPT_L2ENTRY]; - - if(((pte >> PAGE_SHIFT) & 0x0fffffff) == live_p2m[pfn]) - xen_start = (hvirt_start >> L2_PAGETABLE_SHIFT_PAE) & 0x1ff; + int hstart; + unsigned long he; + + hstart = (hvirt_start >> L2_PAGETABLE_SHIFT_PAE) & 0x1ff; + he = ((const uint64_t *) spage)[hstart]; + + if ( ((he >> PAGE_SHIFT) & 0x0fffffff) == m2p_mfn0 ) { + /* hvirt starts with xen stuff... */ + xen_start = hstart; + } else if ( hvirt_start != 0xf5800000 ) { + /* old L2s from before hole was shrunk... */ + hstart = (0xf5800000 >> L2_PAGETABLE_SHIFT_PAE) & 0x1ff; + he = ((const uint64_t *) spage)[hstart]; + + if( ((he >> PAGE_SHIFT) & 0x0fffffff) == m2p_mfn0 ) + xen_start = hstart; + } } if (pt_levels == 4 && type == XEN_DOMCTL_PFINFO_L4TAB) { @@ -550,6 +561,8 @@ static xen_pfn_t *xc_map_m2p(int xc_handle, return NULL; } + m2p_mfn0 = entries[0].mfn; + free(extent_start); free(entries); diff --git a/tools/libxc/xg_save_restore.h b/tools/libxc/xg_save_restore.h index 00d0753def..6275b37ef0 100644 --- a/tools/libxc/xg_save_restore.h +++ b/tools/libxc/xg_save_restore.h @@ -53,8 +53,17 @@ static int get_platform_info(int xc_handle, uint32_t dom, *hvirt_start = xen_params.virt_start; + /* + * XXX For now, 32bit dom0's can only save/restore 32bit domUs + * on 64bit hypervisors, so no need to check which type of domain + * we're dealing with. + */ if (strstr(xen_caps, "xen-3.0-x86_64")) +#if defined(__i386__) + *pt_levels = 3; +#else *pt_levels = 4; +#endif else if (strstr(xen_caps, "xen-3.0-x86_32p")) *pt_levels = 3; else if (strstr(xen_caps, "xen-3.0-x86_32")) diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c index f1b63ffb66..fdc102c1a5 100644 --- a/xen/arch/x86/domctl.c +++ b/xen/arch/x86/domctl.c @@ -356,7 +356,10 @@ void arch_get_info_guest(struct vcpu *v, vcpu_guest_context_u c) c.nat->ctrlreg[3] = xen_pfn_to_cr3(pagetable_get_pfn(v->arch.guest_table)); #ifdef CONFIG_COMPAT else - c.cmp->ctrlreg[3] = compat_pfn_to_cr3(pagetable_get_pfn(v->arch.guest_table)); + { + l4_pgentry_t *l4e = __va(pagetable_get_paddr(v->arch.guest_table)); + c.cmp->ctrlreg[3] = compat_pfn_to_cr3(l4e_get_pfn(*l4e)); + } #endif c(vm_assist = v->domain->vm_assist); diff --git a/xen/include/asm-x86/x86_64/page.h b/xen/include/asm-x86/x86_64/page.h index b1f59b8f13..ecda3a7bf5 100644 --- a/xen/include/asm-x86/x86_64/page.h +++ b/xen/include/asm-x86/x86_64/page.h @@ -96,7 +96,7 @@ typedef l4_pgentry_t root_pgentry_t; #define L3_DISALLOW_MASK (BASE_DISALLOW_MASK | 0x180U /* must-be-zero */) #define L4_DISALLOW_MASK (BASE_DISALLOW_MASK | 0x180U /* must-be-zero */) -#define COMPAT_L3_DISALLOW_MASK 0xFFFFF1E6U /* must-be-zero */ +#define COMPAT_L3_DISALLOW_MASK L3_DISALLOW_MASK #define PAGE_HYPERVISOR (__PAGE_HYPERVISOR | _PAGE_GLOBAL) #define PAGE_HYPERVISOR_NOCACHE (__PAGE_HYPERVISOR_NOCACHE | _PAGE_GLOBAL) -- 2.30.2